<!--- 
kalendar CFC

COPYRIGHT & LICENSING INFO
-------------------------------------------------------------------

Copyright 2006 TJ Downes - tdownes@sanative.net - http://www.sanative.net

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
--->

<cfcomponent displayname="kalendar"
		hint="This CFC is intended to populate a calendar with event data. There are specific fields it requires to properly display the recordset!"
		output="no">

	<!--- Function getSingleRecord ---->
	<cffunction access="public" 
			name="getSingleRecord" 
			output="false" 
			returntype="query" 
			displayname="getSingleRecord" 
			hint="Retrieves a single database record based upon the ID sent. Return output contained in queryDetails variable, of type query.">
			
		<cfargument name="EventID" 
				type="string" 
				required="true" 
				default="" 
				displayname="EventID" 
				hint="The ID of the item to be retrieved. This is the same as the database table fieldname." />
		
		<cfset var queryDetails = "" />
		
		<!--- Query table for a single record. --->
		<cfquery name="queryDetails" datasource="#application.KConfig.getDSN()#">
			
			SELECT
				*
			FROM
				tblKalendar
			WHERE
				EventID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.EventID#" />
		
		</cfquery>
		
		<cfreturn queryDetails />
	
	</cffunction>

	<!--- Function createRecord --->
	<cffunction access="public" 
			name="createRecord" 
			output="false" 
			returntype="string" 
			displayname="createRecord" 
			hint="Adds a new database record. The return output is returnedMessage variable, a string message indicating success or failure.">
			
		<cfargument name="CategoryID" 
				type="numeric" 
				required="yes"
				default="1" 
				displayname="CategoryID" 
				hint="The category id the record belongs to." />
			
		<cfargument name="EventID" 
				type="string" 
				required="yes"
				displayname="EventID" 
				hint="The id of the item." />
			
		<cfargument name="IsPublished" 
				type="boolean" 
				required="false"
				default="0"
				displayname="IsPublished" 
				hint="Specificies if event should be published to the web site." />
			
		<cfargument name="IsFeatured" 
				type="boolean" 
				required="false"
				default="0"
				displayname="IsFeatured" 
				hint="Specificies if event should be published to the web site homepage." />
			
		<cfargument name="StartDate" 
				type="date" 
				required="true"
				displayname="StartDate" 
				hint="The start date of the record." />
			
		<cfargument name="EndDate" 
				type="date" 
				required="true"
				displayname="EndDate" 
				hint="The end date of the record." />
			
		<cfargument name="StartTime" 
				type="string" 
				required="yes"
				displayname="StartTime" 
				hint="The start time of the record." />
			
		<cfargument name="EndTime" 
				type="string" 
				required="no"
				displayname="EndTime" 
				hint="The ending time of the record." />
			
		<cfargument name="ContactPhone" 
				type="string" 
				required="true"
				displayname="ContactPhone" 
				hint="Contact phone number for the venue." />
			
		<cfargument name="ContactName" 
				type="string" 
				required="true"
				displayname="ContactName" 
				hint="Name of the event Contact Person." />
			
		<cfargument name="ContactEmail" 
				type="string" 
				required="true"
				displayname="ContactEmail" 
				hint="Contact person's email." />
				
		<cfargument name="Title" 
				type="string" 
				required="true" 
				displayname="Title" 
				hint="The title of the record." />
				
		<cfargument name="Location" 
				type="string" 
				required="true" 
				displayname="Location" 
				hint="Location for the event." />
				
		<cfargument name="Teaser" 
				type="string" 
				required="true" 
				displayname="Teaser" 
				hint="The teaser description." />
			
		<cfargument name="ExternalURL" 
				type="string" 
				required="true" 
				displayname="ExternalURL" 
				hint="A website address." />
			
		<cfargument name="Description" 
				type="string" 
				required="true"
				displayname="Description" 
				hint="The record contents." />	
		
		<cfset var returnMessage = "New record added." />
		
		<cfif NOT Len(Trim(arguments.EndDate))>
			<cfset arguments.EndDate = arguments.StartDate />
		</cfif>

		<!--- Add new record to table.--->
		
		<cfquery name="createRecord" datasource="#application.KConfig.getDSN()#">
		
			INSERT INTO
				tblKalendar
				(
					CategoryID,
					IsPublished,
					IsFeatured,
					StartDate,
					EndDate, 
					StartTime, 
					EndTime,
					EventID,
					ContactPhone,
					ContactName,
					ContactEmail,
					Title,
					Location,
					Teaser,
					ExternalURL,
					Description
				)
			VALUES
				(
					<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.CategoryID#" />,
					<cfqueryparam cfsqltype="cf_sql_bit" value="#arguments.IsPublished#" />,
					<cfqueryparam cfsqltype="cf_sql_bit" value="#arguments.IsFeatured#" />,
					<cfqueryparam cfsqltype="cf_sql_date" value="#CreateODBCDate(arguments.StartDate)#" />,
					<cfqueryparam cfsqltype="cf_sql_date" value="#CreateODBCDate(arguments.EndDate)#" />, 
					<cfif Len(Trim(arguments.StartTime))><cfqueryparam cfsqltype="cf_sql_time" value="#CreateODBCTime(arguments.StartTime)#" /><cfelse>NULL</cfif>, 
					<cfif Len(Trim(arguments.EndTime))><cfqueryparam cfsqltype="cf_sql_time" value="#CreateODBCTime(arguments.EndTime)#" /><cfelse>NULL</cfif>,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.EventID#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ContactPhone)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ContactName)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ContactEmail)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Title)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Location)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Teaser)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ExternalURL)#" />,
					<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Description)#" />
				) 
				
		</cfquery>

		<cfreturn returnMessage />
				
	</cffunction>

	<!--- Function updateRecord --->
	<cffunction access="public" 
			name="updateRecord" 
			output="false" 
			returntype="string" 
			displayname="updateRecord" 
			hint="Updates a single database record based upon the ID sent. The return output is returnMessage variable, a string message indicating success or failure.">
			
		<cfargument name="EventID" 
				type="string" 
				required="true"
				displayname="EventID" 
				hint="The ID of the record to be updated." />
			
		<cfargument name="CategoryID" 
				type="numeric" 
				required="yes"
				default="1" 
				displayname="CategoryID" 
				hint="The category id the record belongs to." />
			
		<cfargument name="IsPublished" 
				type="boolean" 
				required="false"
				default="0"
				displayname="IsPublished" 
				hint="Specificies if event should be published to the web site." />
			
		<cfargument name="IsFeatured" 
				type="boolean" 
				required="false"
				default="0"
				displayname="IsFeatured" 
				hint="Specificies if event should be published to the web site homepage." />
			
		<cfargument name="IsDeleted" 
				type="boolean" 
				required="false"
				default="0"
				displayname="IsDeleted" 
				hint="Specificies if event should be deleted." />
			
		<cfargument name="StartDate" 
				type="date" 
				required="true"
				displayname="StartDate" 
				hint="The start date of the record." />
			
		<cfargument name="EndDate" 
				type="date" 
				required="true"
				displayname="EndDate" 
				hint="The end date of the record." />
			
		<cfargument name="StartTime" 
				type="string" 
				required="yes"
				displayname="StartTime" 
				hint="The start time of the record." />
			
		<cfargument name="EndTime" 
				type="string" 
				required="no"
				displayname="EndTime" 
				hint="The ending time of the record." />
			
		<cfargument name="ContactPhone" 
				type="string" 
				required="true"
				displayname="ContactPhone" 
				hint="Contact phone number for the venue." />
			
		<cfargument name="ContactName" 
				type="string" 
				required="true"
				displayname="ContactName" 
				hint="Name of the event Contact Person." />
			
		<cfargument name="ContactEmail" 
				type="string" 
				required="true"
				displayname="ContactEmail" 
				hint="Contact person's email." />
				
		<cfargument name="Title" 
				type="string" 
				required="true" 
				displayname="Title" 
				hint="The title of the record." />
				
		<cfargument name="Location" 
				type="string" 
				required="true" 
				displayname="Location" 
				hint="Location for the event." />
				
		<cfargument name="Teaser" 
				type="string" 
				required="true" 
				displayname="Teaser" 
				hint="The teaser description." />
			
		<cfargument name="ExternalURL" 
				type="string" 
				required="true" 
				displayname="ExternalURL" 
				hint="A website address." />
			
		<cfargument name="Description" 
				type="string" 
				required="true"
				displayname="Description" 
				hint="The record contents." />

		<cfset var returnMessage = "Record has been updated." />
		
		<!--- Update Record --->
		<cfif NOT Len(Trim(arguments.EndDate))>
			<cfset arguments.EndDate = arguments.StartDate />
		</cfif>
		
		<cfquery name="updateRecord" datasource="#application.KConfig.getDSN()#">
		
			UPDATE
				tblKalendar
			SET
				CategoryID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.CategoryID#" />,
				IsPublished = <cfqueryparam cfsqltype="cf_sql_bit" value="#arguments.IsPublished#" />,
				IsFeatured = <cfqueryparam cfsqltype="cf_sql_bit" value="#arguments.IsFeatured#" />,
				IsDeleted = <cfqueryparam cfsqltype="cf_sql_bit" value="#arguments.IsDeleted#" />,
				StartDate = <cfqueryparam cfsqltype="cf_sql_date" value="#CreateODBCDate(arguments.StartDate)#" />,
				EndDate = <cfqueryparam cfsqltype="cf_sql_date" value="#CreateODBCDate(arguments.EndDate)#" />, 
				StartTime = <cfif Len(Trim(arguments.StartTime))><cfqueryparam cfsqltype="cf_sql_time" value="#CreateODBCTime(arguments.StartTime)#" /><cfelse>NULL</cfif>, 
				EndTime = <cfif Len(Trim(arguments.EndTime))><cfqueryparam cfsqltype="cf_sql_time" value="#CreateODBCTime(arguments.EndTime)#" /><cfelse>NULL</cfif>,
				ContactPhone = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ContactPhone)#" />,
				ContactName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ContactName)#" />,
				ContactEmail = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ContactEmail)#" />,
				Title = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Title)#" />,
				Location = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Location)#" />,
				Teaser = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Teaser)#" />,
				ExternalURL = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.ExternalURL)#" />,
				Description = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(arguments.Description)#" />
			WHERE
				EventID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.EventID#" />
			
		</cfquery>
		
		<cfreturn returnMessage />
				
	</cffunction>

	<!--- Function deleteRecord --->
	<cffunction access="public" 
			name="deleteRecord" 
			output="false" 
			returntype="string" 
			displayname="deleteRecord" 
			hint="Deletes a single database record based upon the ID sent. The return output is returnMessage variable, a string message indicating success or failure.">
			
		<cfargument name="EventID" 
				type="string" 
				required="true"
				displayname="EventID" 
				hint="The ID of the article to be deleted." />

		<cfset var returnMessage = "Record deleted." />
		
		<!--- Delete the record --->
		<cfquery name="deleteRecord" datasource="#application.KConfig.getDSN()#">
		
			UPDATE
				tblKalendar
			SET
				IsDeleted = 1
			WHERE
				EventID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.EventID#" />
			
		</cfquery>
		
		<cfreturn returnMessage />
				
	</cffunction>
	
	<!--- get calendar --->
	<cffunction access="public" 
		name="getCalendar" 
		output="false" 
		returntype="array" 
		displayname="getCalendar" 
		hint="gets data for calendar and converts to a 2d double nested array">
			
		<cfargument name="view" 
				type="string" 
				required="true"
				displayname="view"
				default="week" 
				hint="sets the calendar to display week or month view" />
				
		<cfargument name="LinkDate" 
				type="date" 
				required="yes"
				displayname="LinkDate"
				default="#DateFormat(Now(), 'mmmm d, yyyy')#" 
				hint="sets linking and date mechanisms for the calendar." />
				
		<cfargument name="PublicOnly" 
				type="boolean" 
				required="yes"
				displayname="PublicOnly"
				default="1" 
				hint="Specifies to display events marked only for public consumption." />
				
		<cfargument name="CategoryID" 
				type="numeric" 
				required="yes"
				displayname="CategoryID"
				default="0" 
				hint="allows querying of records by category." />
		
		<cfscript>
			var CalendarEvents = ArrayNew(1);
			var ArrayCount = 0;
			var thisDayOfWeek = "";
			var FirstDateOfWeek = "";
			var LastDateOfWeek = "";
			var FirstDateOfMonth = "";
			var LastDateOfMonth = "";
			var DayOfWeekForFirstDateOfMonth = "";
			var DayOfWeekForLastDateOfMonth = "";
		</cfscript>
		
		<!--- 
		this is the same set of variables found in kalendar to set the start and end of
		the calendar range. This should not be modified.
		 --->
		<cfswitch expression="#arguments.view#">
			<cfcase value="day">
				<cfscript>
					thisDayOfWeek = DayOfWeek(arguments.LinkDate);
					FirstDateOfWeek = CreateODBCDateTime(DateFormat(arguments.LinkDate, "m/d/yyyy") & " " & "12:00:00 AM");
					LastDateOfWeek = CreateODBCDateTime(DateFormat(arguments.LinkDate, "m/d/yyyy") & " " & "11:59:59 PM");
				</cfscript>
			</cfcase>
			<cfcase value="week">
				<cfscript>
					thisDayOfWeek = -DayOfWeek(arguments.LinkDate) + 1;
					FirstDateOfWeek = CreateODBCDate(DateAdd('d', thisDayOfWeek, arguments.LinkDate));
					LastDateOfWeek = CreateODBCDate(DateAdd('d', 7, FirstDateOfWeek));
				</cfscript>
			</cfcase>
			<cfdefaultcase>
				<cfscript>
					FirstDateOfMonth = Month(arguments.LinkDate) & "/1/" &  Year(arguments.LinkDate);
					FirstDateOfMonth = CreateODBCDate(FirstDateOfMonth);
					LastDateOfMonth = Month(arguments.LinkDate) & "/" & DaysInMonth(FirstDateOfMonth) & "/" &  Year(arguments.LinkDate);
					LastDateOfMonth = CreateODBCDate(LastDateOfMonth);
					DayOfWeekForFirstDateOfMonth = -DayOfWeek(FirstDateOfMonth) + 1;
					FirstDateOfWeek = CreateODBCDate(DateAdd('d', DayOfWeekForFirstDateOfMonth, FirstDateOfMonth));
					DayOfWeekForLastDateOfMonth = 7 - DayOfWeek(LastDateOfMonth);
					LastDateOfWeek = CreateODBCDate(DateAdd('d', DayOfWeekForLastDateOfMonth, LastDateOfMonth));
				</cfscript>
			</cfdefaultcase>
		</cfswitch>

		<!--- query for events --->
		<cfquery name="getCalendar" datasource="#application.KConfig.getDSN()#">

			SELECT
				tblKalendar.*,
				tblKalendarCategories.CategoryName,
				tblKalendarCategories.CategoryBGColor,
				tblKalendarCategories.CategoryTextColor
			FROM
				tblKalendarCategories RIGHT OUTER JOIN
					tblKalendar ON tblKalendarCategories.CategoryID = tblKalendar.CategoryID
			WHERE
				IsDeleted = 0
			<cfswitch expression="#arguments.view#">
				<cfcase value="day">
			AND
				(
					StartDate <= <cfqueryparam cfsqltype="cf_sql_date" value="#FirstDateOfWeek#" />
				AND
					EndDate >= <cfqueryparam cfsqltype="cf_sql_date" value="#LastDateOfWeek#" />
				)
				</cfcase>
				<cfdefaultcase>
			AND
				(
					(
						StartDate >= <cfqueryparam cfsqltype="cf_sql_date" value="#FirstDateOfWeek#" />
					OR
				  		EndDate >= <cfqueryparam cfsqltype="cf_sql_date" value="#FirstDateOfWeek#" />
				  	)
			AND
					(
						StartDate <= <cfqueryparam cfsqltype="cf_sql_date" value="#LastDateOfWeek#" />
					OR
						EndDate <= <cfqueryparam cfsqltype="cf_sql_date" value="#LastDateOfWeek#" />
					)
				)

				</cfdefaultcase>
			</cfswitch>
			<cfif arguments.PublicOnly>
			AND
				IsPublished = 1
			</cfif>
			<cfif arguments.CategoryID neq 0>
			AND
				tblKalendarCategories.CategoryID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.CategoryID#" />
			</cfif>
			ORDER BY 
				StartDate,
				StartTime,
				EndDate,
				EndTime

		</cfquery> 

		<!--- convert query to array --->
		
		<cfoutput query="getCalendar" group="EventID">
			<cfscript>
				ArrayCount = ArrayCount + 1;
				CalendarEvents[ArrayCount] = StructNew();
			</cfscript>
		<cfoutput>
			<cfscript>
				CalendarEvents[ArrayCount].StartDate = StartDate;
				CalendarEvents[ArrayCount].EndDate = EndDate;
				CalendarEvents[ArrayCount].EndTime = EndTime;
				CalendarEvents[ArrayCount].EventIDLabel = "EventID";
				CalendarEvents[ArrayCount].EventID = EventID;
				CalendarEvents[ArrayCount].Title = Trim(Title);
				CalendarEvents[ArrayCount].Teaser = Trim(Teaser);
				CalendarEvents[ArrayCount].Description = Trim(Description);
				CalendarEvents[ArrayCount].Location = Trim(Location);
				CalendarEvents[ArrayCount].ExternalURL = Trim(ExternalURL);
				CalendarEvents[ArrayCount].CategoryName = CategoryName;
				CalendarEvents[ArrayCount].ContactName = ContactName;
				CalendarEvents[ArrayCount].ContactPhone = ContactPhone;
				CalendarEvents[ArrayCount].ContactEmail = ContactEmail;
				CalendarEvents[ArrayCount].StartTime = StartTime;
				CalendarEvents[ArrayCount].CategoryBGColor = CategoryBGColor;
				CalendarEvents[ArrayCount].CategoryTextColor = CategoryTextColor;
			</cfscript>
		</cfoutput>
		</cfoutput>
		
		<cfreturn CalendarEvents /> 

	</cffunction>
	
	
	<!--- Function KalendarXML --->
	<cffunction access="remote" 
			name="KalendarXML" 
			output="false" 
			returntype="xml" 
			displayname="KalendarXML" 
			hint="Creates XML from resultset of getCalendar">
			
		<cfargument name="view" 
				type="string" 
				required="true"
				displayname="view"
				default="month" 
				hint="sets the calendar to display week or month view" />
				
		<cfargument name="LinkDate" 
				type="date" 
				required="yes"
				displayname="LinkDate"
				default="#DateFormat(Now(), 'mmmm d, yyyy')#" 
				hint="sets linking and date mechanisms for the calendar." />
				
		<cfargument name="PublicOnly" 
				type="boolean" 
				required="yes"
				displayname="PublicOnly"
				default="1" 
				hint="Specifies to display events marked only for public consumption." />
				
		<cfargument name="CategoryID" 
				type="numeric" 
				required="yes"
				displayname="CategoryID"
				default="0" 
				hint="allows querying of records by category." />
				
		<cfscript>
			var publishDate = DateConvert("local2Utc", Now());
			var eventdate = "";
			var description = "";
			var category = "";
			var eventid = "";
			var rssFeed = "";
			publishDate = DateFormat(publishDate, "ddd, dd mmm yyyy") & " " & TimeFormat(publishDate, "HH:mm:ss") & " GMT";
			rss.KalendarData = getCalendar("month", arguments.LinkDate, 1, arguments.CategoryID);
		</cfscript>
		
		<cfxml variable="rssFeed"><cfprocessingdirective suppresswhitespace="yes">
<rss version="2.0">
	<channel>
		<title>Kalendar of Events for <cfoutput>#DateFormat(arguments.LinkDate, "mmmm yyyy")#</cfoutput></title>
		<link>http://<cfoutput>#cgi.SERVER_NAME##cgi.SCRIPT_NAME#</cfoutput></link>
		<description>Latest Events</description>
		<language>en-us</language>
		<copyright>Copyright 2006 TJ Downes</copyright>
		<pubDate><cfoutput>#publishDate#</cfoutput></pubDate>
		<lastBuildDate><cfoutput>#publishDate#</cfoutput></lastBuildDate>
		<generator>Kalendar</generator>
		<docs>http://cfopen.org/docman/?group_id=102</docs>
		<managingEditor><cfoutput>#Trim(application.KConfig.getRSSEditor())#</cfoutput></managingEditor>
		<webMaster><cfoutput>#Trim(application.KConfig.getRSSWebmaster())#</cfoutput></webMaster>
		<cfloop index="i" from="1" to="#ArrayLen(rss.KalendarData)#">
				<cfif Month(rss.KalendarData[i].StartDate) eq Month(LinkDate)>
					<cfscript>
					  title = XMLFormat(rss.KalendarData[i].Title);
					  if(Len(Trim(rss.KalendarData[i].StartTime))) {
					  	eventdate = DateConvert("local2Utc", DateFormat(rss.KalendarData[i].StartDate, "m/d/yyyy") & " " & rss.KalendarData[i].StartTime);
						} else {
						eventdate = DateConvert("local2Utc", rss.KalendarData[i].StartDate);
						}
					  eventdate = DateFormat(eventdate, "ddd, dd mmm yyyy") & " " & TimeFormat(eventdate, "HH:mm:ss") & " GMT";
					  description = XMLFormat(rss.KalendarData[i].Description);
					  category = XMLFormat(Trim(rss.KalendarData[i].CategoryName));
					  eventid = rss.KalendarData[i].EventID;
					</cfscript><cfoutput><item>
			<title>#title#</title>
			<description>#description#</description>
			<link>http://#cgi.SERVER_NAME#/#cgi.SCRIPT_NAME#</link>
			<category>#category#</category>
			<pubDate>#eventdate#</pubDate>
			<guid>http://#cgi.SERVER_NAME##Replace(cgi.SCRIPT_NAME, ListLast(cgi.SCRIPT_NAME, "/"), "eventDetails.cfm")#?eventid=#eventid#</guid>
		</item></cfoutput></cfif></cfloop>
	</channel>
</rss></cfprocessingdirective></cfxml>
		<cfreturn rssFeed />
				
	</cffunction>
		
</cfcomponent>